import { Algorithm } from "../types"

interface AnomalousEdge {
  from_node: string
  to_node: string
  anomaly_score: number
}

interface GraphNode {
  id: string
  name?: string
  properties?: Array<{
    name: string
    value: any
  }>
}

interface GraphEdge {
  id: string
  from_node: string
  to_node: string
  name?: string
  properties?: Array<{
    name: string
    value: any
  }>
}

interface KnowledgeGraph {
  nodes: GraphNode[]
  edges: GraphEdge[]
}

interface GraphInput {
  graph: KnowledgeGraph
  threshold: number
  has_labels: boolean
}

interface Metric {
  precision?: number
  recall?: number
  f1_score?: number
  auc?: number
}

export const anomalousEdgeDetection: Algorithm = {
  name: "异常边检测算法",
  description: "异常边检测算法(AEDS)算法，用于识别图结构中随时间变化的异常模式",
  configOptions: [
    {
      id: "threshold",
      label: "异常阈值",
      type: "number",
      defaultValue: 0.7,
    },
    {
      id: "has_labels",
      label: "是否包含标签",
      type: "select",
      options: ["true", "false"],
      defaultValue: "false",
    },
    {
      id: "inputData",
      label: "输入数据",
      type: "textarea",
      placeholder: `请输入JSON格式的图数据，例如：
{
  "nodes": [
    {
      "id": "1",
      "name": "节点1",
      "properties": [{"name": "属性1", "value": "值1"}]
    }
  ],
  "edges": [
    {
      "id": "edge1",
      "from_node": "1",
      "to_node": "2",
      "name": "关系1",
      "properties": [{"name": "属性1", "value": "值1"}]
    }
  ]
}`
    }
  ],
  execute: async (config) => {
    try {
      // 生成唯一的任务ID
      const taskId = `aeds_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
      
      // 解析和验证输入数据
      let graphData: KnowledgeGraph
      if (typeof config.inputData === 'string') {
        try {
          if (!config.inputData.trim()) {
            throw new Error("输入数据不能为空")
          }

          const cleanInput = config.inputData.trim()
          
          // 添加调试信息
          console.log("接收到的输入数据:", cleanInput)
          
          try {
            graphData = JSON.parse(cleanInput)
          } catch (parseError: any) {
            throw new Error(`JSON解析错误: ${parseError.message}\n请确保输入的是有效的JSON格式`)
          }

          // 验证图数据结构
          if (!graphData || typeof graphData !== 'object') {
            throw new Error("输入数据必须是一个JSON对象")
          }
          
          if (!graphData.nodes) {
            throw new Error("图数据缺少nodes字段")
          }
          
          if (!graphData.edges) {
            throw new Error("图数据缺少edges字段")
          }

          if (!Array.isArray(graphData.nodes)) {
            throw new Error("图数据格式错误：nodes必须是数组")
          }
          if (!Array.isArray(graphData.edges)) {
            throw new Error("图数据格式错误：edges必须是数组")
          }

          // 验证节点格式
          graphData.nodes.forEach((node, index) => {
            if (!node.id) {
              throw new Error(`节点格式错误：第${index + 1}个节点缺少id字段`)
            }
          })

          // 验证边格式
          graphData.edges.forEach((edge, index) => {
            if (!edge.id) {
              throw new Error(`边格式错误：第${index + 1}条边缺少id字段`)
            }
            if (!edge.from_node || !edge.to_node) {
              throw new Error(`边格式错误：第${index + 1}条边缺少from_node或to_node字段`)
            }
          })

        } catch (e) {
          if (e instanceof SyntaxError) {
            throw new Error("JSON格式错误，请确保输入正确的JSON格式数据")
          }
          throw e
        }
      } else {
        throw new Error("输入数据必须是JSON字符串")
      }

      // 准备请求数据
      const requestData: {
        task_id: string;
        task_callback_url: string;
        input_params: GraphInput;
      } = {
        task_id: taskId,
        task_callback_url: "",
        input_params: {
          graph: {
            nodes: graphData.nodes,
            edges: graphData.edges
          },
          threshold: Number(config.threshold) || 0.7,  // 使用默认值0.7
          has_labels: config.has_labels === "true"
        }
      }

      // 添加请求数据日志
      console.log('发送的请求数据:', JSON.stringify(requestData, null, 2))

      // 创建任务
      const createResponse = await fetch("http://172.16.4.151:1122/api/aeds/create", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify(requestData)
      })

      if (!createResponse.ok) {
        const errorData = await createResponse.json()
        
        // 专门处理422错误
        if (createResponse.status === 422) {
          const validationErrors = errorData.detail || []
          const errorMessages = Array.isArray(validationErrors) 
            ? validationErrors.map(err => {
                if (typeof err === 'object') {
                  return `${err.loc?.join('.')}: ${err.msg}`
                }
                return err
              }).join('\n')
            : errorData.detail || "数据验证失败"
          
          throw new Error(`数据验证错误:\n${errorMessages}\n\n请检查输入数据格式是否符合要求。`)
        }
        
        throw new Error(errorData.detail || "创建任务失败")
      }

      const createResult = await createResponse.json()

      // 执行任务
      const executeResponse = await fetch(`http://172.16.4.151:1122/api/aeds/execute/${taskId}`, {     
        method: "POST"
      })

      if (!executeResponse.ok) {
        const errorData = await executeResponse.json()
        throw new Error(errorData.detail || "执行任务失败")
      }

      const executeResult = await executeResponse.json()

      // 轮询获取结果
      let result
      let attempts = 0
      const maxAttempts = 60 // 最多等待60秒

      while (attempts < maxAttempts) {
        const getResultResponse = await fetch(`http://172.16.4.151:1122/api/aeds/result/${taskId}`)
        
        if (!getResultResponse.ok) {
          const errorData = await getResultResponse.json()
          throw new Error(errorData.detail || "获取结果失败")
        }

        result = await getResultResponse.json()

        if (result.task_status === "COMPLETED") {
          break
        } else if (result.task_status === "FAILED") {
          throw new Error(result.error_message || "任务执行失败")
        }

        // 等待1秒后重试
        await new Promise(resolve => setTimeout(resolve, 1000))
        attempts++
      }

      if (attempts >= maxAttempts) {
        throw new Error("任务执行超时")
      }

      // 处理结果
      const outputParams = result.output_params
      const resultText = `检测完成：
总边数: ${outputParams.total_edges}
异常边数: ${outputParams.anomalous_count}
异常比例: ${((outputParams.anomalous_count / outputParams.total_edges) * 100).toFixed(2)}%

异常边列表:
${outputParams.anomalous_edges
  .sort((a: AnomalousEdge, b: AnomalousEdge) => b.anomaly_score - a.anomaly_score)
  .map((edge: AnomalousEdge) => 
    `- ${edge.from_node} -> ${edge.to_node} (异常分数: ${edge.anomaly_score.toFixed(4)})`
  ).join('\n')}`

      // 如果有性能指标，添加到结果中
      const metricsText = result.metrics?.length ? `

算法性能指标:
${result.metrics.map((metric: Metric) => 
  `- 准确率(Precision): ${metric.precision?.toFixed(4) || 'N/A'}
- 召回率(Recall): ${metric.recall?.toFixed(4) || 'N/A'}
- F1分数: ${metric.f1_score?.toFixed(4) || 'N/A'}
- AUC: ${metric.auc?.toFixed(4) || 'N/A'}`
).join('\n')}` : '';

      return {
        result: resultText + metricsText,
        steps: result.metrics || [],
        executionTime: `${result.execution_time || 0}ms`,
        details: {
          anomalousEdges: outputParams.anomalous_edges,
          totalEdges: outputParams.total_edges,
          anomalousCount: outputParams.anomalous_count,
          metrics: result.metrics
        }
      }
    } catch (e) {
      throw e
    }
  }
}